Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update thumbnails only when they are visible (to improve scrolling through large documents) #5586

Merged

Conversation

fkaelberer
Copy link
Contributor

This PR postpones highlighting the current page thumbnail in PDFThumbnailViewer.scrollThumbnailIntoView() until the thumbnail view is opened. Setting the style of thumbnails can take long and become a bottleneck if the document (and thus, the DOM tree) is very large. Scrolling through very large documents is now smoother with this PR.

Good tests:
[1] pdf (2000+ pages) from #5207 and
[2] pdf (3000+ pages) from https://bugzilla.mozilla.org/show_bug.cgi?id=885287#c6.
[3] pdf (5000+ pages)

A benchmark: Scrolling through the first 50 pages of [3] with the key:

Browser w/o patch w/ patch
FF 34 1:01 0:49
FF Nightly 37.0a1 1:50 1:07

Another benchmark: While scrolling through the first 10 pages of [1] with the key, the frame rates are now much more often at the 60 fps mark (FF Nightly 37.0a1):
zwischenablage03
zwischenablage04

EDIT: Added correct link to [3] which I had used for benchmarking, added Firefox 34 results (which shows performance regression of Nightly)

@CodingFabian
Copy link
Contributor

good first step. i think with regards to reflow there are quite a few optimizations possible.

@yurydelendik
Copy link
Contributor

really good. is there a reason why we cannot just cancel scrollThumbnailIntoView from 'pagechange' completely when !isThumbnailViewEnabled? (the patch looks a little bit "asymmetrical" IMHO) I'm trying to avoid this.renderingQueue.isThumbnailViewEnabled check and refreshing during its state update from different location (which is still named scrollThumbnailIntoView).

@fkaelberer
Copy link
Contributor Author

Is there a reason why we cannot just cancel scrollThumbnailIntoView from 'pagechange' completely when !isThumbnailViewEnabled?

Maybe not. Returning immediately if !isThumbnailViewEnabled seems to work as well. But I didn't want to be too obtrusive with my changes. Maybe someone (who is more familiar with the viewer) can even find a better patch now that I have pointed to the performance issue.

Also I'm not too happy with the reference to the rendering queue in this.renderingQueue.isThumbnailViewEnabled to check if the sidebar is open. Is there a more direct check?

@fkaelberer
Copy link
Contributor Author

I updated the commit. Now scrollThumbnailIntoView is only called if PDFViewerApplication.sidebarOpen. This is cleaner and addresses @yurydelendik's comments.

@CodingFabian
Copy link
Contributor

this solves quite a few concerns for us. thanks!

@Snuffleupagus
Copy link
Collaborator

I've found one small issue with this patch:
If you manage to open the sidebar when the PDF file is loading, but before the pages have started rendering, only the first two thumbnails are drawn and the following is printed in the console:

TypeError: thumbnail is null                                   thumbnail_view.js:299:6

Probably the easiest way to solve this is to check if (thumbnail) before thumbnail_view.js#L299.

@fkaelberer fkaelberer force-pushed the updateThumbnailClassesOnlyWhenVisible branch from 9aa3b24 to 4271bf4 Compare December 28, 2014 18:25
@fkaelberer
Copy link
Contributor Author

@Snuffleupagus: I didn't manage to reproduce the warning, but I added the check anyway. Thanks.

@Snuffleupagus
Copy link
Collaborator

/botio-linux preview

@pdfjsbot
Copy link

From: Bot.io (Linux)


Received

Command cmd_preview from @Snuffleupagus received. Current queue size: 0

Live output at: http://107.21.233.14:8877/3c8cc003d4850d0/output.txt

@Snuffleupagus
Copy link
Collaborator

@Snuffleupagus: I didn't manage to reproduce the warning, but I added the check anyway. Thanks.

I can confirm that this fixes the issue I was seeing!

@fkaelberer fkaelberer force-pushed the updateThumbnailClassesOnlyWhenVisible branch from 4271bf4 to 6f99d68 Compare January 2, 2015 17:42
@fkaelberer
Copy link
Contributor Author

I added a second commit: Update thumbnail images only when sidebar is visible.

This finally makes scrolling smooth as butter, as long as thumbnails are off. Updating the thumbnail images causes one or two reflows (setting the image and setting the data-loaded css class), which were causing the lags.

Browser w/o patch w/ patch w/ 2nd patch
FF 34 1:01 0:49 0:46
FF Nightly 37.0a1 1:50 1:07 0:46

zwischenablage01

@fkaelberer fkaelberer changed the title Update thumbnail style only when they are visible (to improve scrolling through large documents) Update thumbnails only when they are visible (to improve scrolling through large documents) Jan 2, 2015
@timvandermeij
Copy link
Contributor

/botio-linux preview

@pdfjsbot
Copy link

pdfjsbot commented Jan 2, 2015

From: Bot.io (Linux)


Received

Command cmd_preview from @timvandermeij received. Current queue size: 0

Live output at: http://107.21.233.14:8877/16397a37e238e5e/output.txt

@timvandermeij
Copy link
Contributor

Fixes #3120. Really nice work!

@@ -1221,6 +1221,23 @@ var PDFViewerApplication = {
}
},

refreshSidebar: function pdfViewOpenSidebar() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: refreshSidebar seems like a slightly strange name, since the function only updates the thumbnails. How about refreshThumbnailViewer or something similar?

@fkaelberer fkaelberer force-pushed the updateThumbnailClassesOnlyWhenVisible branch from 6f99d68 to cd22b9b Compare January 3, 2015 09:31
@fkaelberer
Copy link
Contributor Author

@Snuffleupagus I agree. Commit is updated.

@fkaelberer fkaelberer force-pushed the updateThumbnailClassesOnlyWhenVisible branch from cd22b9b to 30b3bb4 Compare January 4, 2015 16:19
@fkaelberer
Copy link
Contributor Author

I also changed the css style of the hidden sidebar container from visibility: hidden (= do the reflow and show things transparently) to display: none. This saves layouting of 4 extra DOM elements per page and so makes everything even smoother (it almost makes the first two commits obsolete ;-)

@Snuffleupagus
Copy link
Collaborator

I also changed the css style of the hidden sidebar container from visibility: hidden (= do the reflow and show things transparently) to display: none.

This is a great idea, but unfortunately it causes the "open sidebar" animation to behave strangely. The sidebar now opens instantaneously, while the toolbar still transitions correctly. Interestingly the "close" animation still works as it should.
To easily reproduce this, try increasing the transition-duration to a couple of seconds (instead of the current 200ms).

@fkaelberer fkaelberer force-pushed the updateThumbnailClassesOnlyWhenVisible branch from 30b3bb4 to 4555b56 Compare January 5, 2015 07:40
@fkaelberer
Copy link
Contributor Author

@Snuffleupagus You're right, good point. It seems like this cannot be fixed in pure CSS, because the display property does not support transition. Since there's no trivial fix to this, I removed the commit again.

So I see three possibilities for this change:

  1. Reject the idea
  2. It might be possible to fix the transition with JavaScript and a timer (less elegant. I'd open a separate PR)
  3. Somebody has a more elegant idea.

Reasons for 1: It's only relevant in edge cases, where documents have thousands of pages and thumbs are off. And performance issues are mostly resolved already in this PR. Solution 2 is kinda hacky.

Reasons for 2: A slimmer DOM tree is always welcome, and removing thousands of DOM elements from the layout are definitely noticeable in the UI responsiveness for large documents. Also saves some memory (1KB / page).

Any opinions?

@CodingFabian
Copy link
Contributor

preferring display: none over visibility hidden is a good idea. it should be worked on in a follow up pr.

@Snuffleupagus
Copy link
Collaborator

My opinion is that we should not regress the current behaviour. I think we can try to implement the display: none (or similar) idea in a follow-up PR instead.

@Snuffleupagus
Copy link
Collaborator

@fkaelberer Will manually setting the height/width to 0 instead of using display: none achive the same result? If so, doing something like this might just work:

diff --git a/web/viewer.css b/web/viewer.css
index 91e64ea..affcc9a 100644
--- a/web/viewer.css
+++ b/web/viewer.css
@@ -166,7 +166,8 @@ html[dir='rtl'] .innerCenter {
   top: 0;
   bottom: 0;
   width: 200px;
-  visibility: hidden;
+  max-height: 0px;
+  max-width: 0px;
   -webkit-transition-duration: 200ms;
   -webkit-transition-timing-function: ease;
   transition-duration: 200ms;
@@ -186,7 +187,8 @@ html[dir='rtl'] #sidebarContainer {

 #outerContainer.sidebarMoving > #sidebarContainer,
 #outerContainer.sidebarOpen > #sidebarContainer {
-  visibility: visible;
+  max-height: inherit;
+  max-width: inherit;
 }
 html[dir='ltr'] #outerContainer.sidebarOpen > #sidebarContainer {
   left: 0px;

@fkaelberer
Copy link
Contributor Author

Needs merge.

@fkaelberer fkaelberer force-pushed the updateThumbnailClassesOnlyWhenVisible branch from 4555b56 to 6aa5d5c Compare January 6, 2015 22:10
@fkaelberer
Copy link
Contributor Author

Merged.

@CodingFabian
Copy link
Contributor

I think together with #5617 this is good to go.

@fkaelberer
Copy link
Contributor Author

I reported the scrolling performance regression of FF37 upstream:
https://bugzilla.mozilla.org/show_bug.cgi?id=1117322

@timvandermeij
Copy link
Contributor

@fkaelberer Could you rebase this since the thumbnail code has been refactored in #5673?

@fkaelberer fkaelberer force-pushed the updateThumbnailClassesOnlyWhenVisible branch from 6aa5d5c to d3022e1 Compare January 27, 2015 20:26
@fkaelberer
Copy link
Contributor Author

Rebased.

@yurydelendik
Copy link
Contributor

/botio-windows preview

@pdfjsbot
Copy link

From: Bot.io (Windows)


Received

Command cmd_preview from @yurydelendik received. Current queue size: 0

Live output at: http://107.22.172.223:8877/a93b27c12834f05/output.txt

yurydelendik added a commit that referenced this pull request Feb 27, 2015
…enVisible

Update thumbnails only when they are visible (to improve scrolling through large documents)
@yurydelendik yurydelendik merged commit ce12259 into mozilla:master Feb 27, 2015
@yurydelendik
Copy link
Contributor

Thank you

speedplane pushed a commit to speedplane/pdf.js that referenced this pull request Mar 4, 2015
…sOnlyWhenVisible

Update thumbnails only when they are visible (to improve scrolling through large documents)
@fkaelberer fkaelberer deleted the updateThumbnailClassesOnlyWhenVisible branch March 15, 2015 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants